home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
xgrasp.zip
/
PARSER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-24
|
7KB
|
354 lines
#ident "@(#)parser.c 1.8 91/04/01 XGRASP"
/*-
* parser.c - grasp language file parser.
*
* Copyright (c) 1991 by Patrick J. Naughton
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* This file is provided AS IS with no warranties of any kind. The author
* shall have no liability with respect to the infringement of copyrights,
* trade secrets or any patents by this file or any part thereof. In no
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*
* Comments and additions should be sent to the author:
*
* Patrick J. Naughton
* Sun Microsystems
* 2550 Garcia Ave, MS 10-20
* Mountain View, CA 94043
* (415) 336-1080
*
*/
#include "grasp.h"
char *tokens[] = {
"notoken",
"box",
"break",
"call",
"cfade",
"cfree",
"cgetbuf",
"chgcolor",
"circle",
"clearscr",
"cload",
"closegl",
"color",
"cycle",
"data",
"databegin",
"dataend",
"dataskip",
"dfree",
"dload",
"edge",
"else",
"endlfloat",
"endif",
"exec",
"exit",
"ffree",
"fgaps",
"fload",
"float",
"fly",
"font",
"fstyle",
"getcolor",
"getkey",
"gosub",
"goto",
"if",
"ifkey",
"ifmem",
"ifmouse",
"ifvideo",
"int",
"line",
"link",
"local",
"loop",
"mark",
"merge",
"mode",
"mouse",
"move",
"noise",
"note",
"offset",
"opengl",
"out",
"palette",
"pan",
"pfade",
"pfree",
"pgetbuf",
"pload",
"pnewbuf",
"point",
"poke",
"pokel",
"pokew",
"pop",
"position",
"psave",
"psetbuf",
"putoff",
"putup",
"rect",
"resetgl",
"resetscr",
"return",
"revpage",
"send",
"set",
"setcolor",
"setpage",
"setrgb",
"setupscr",
"split",
"spread",
"text",
"tile",
"timer",
"tran",
"video",
"waitkey",
"when",
"window",
"fade",
"wait",
};
static char *
sows(ptr)
char *ptr;
{
int incomment = 0;
while (incomment || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' ||
*ptr == ',' || *ptr == ';') {
if (*ptr == ';')
incomment = 1;
else if (*ptr == '\n')
break;
ptr++;
}
return ptr;
}
static char *
sowsanl(ptr)
char *ptr;
{
int incomment = 0;
while (incomment || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' ||
*ptr == ',' || *ptr == ';' || *ptr == '\n') {
if (*ptr == ';')
incomment = 1;
else if (*ptr == '\n')
incomment = 0;
ptr++;
}
return ptr;
}
static char *
copytoken(src, dst)
char *src;
char *dst;
{
src = sowsanl(src);
if (*src == '"') {
src++;
while (*src != '"' && *src != '\n' && *src != '\r')
*dst++ = *src++;
if (*src != '\n')
src++;
} else
while (*src != ' ' && *src != '\t' && *src != '\r' &&
*src != ',' && *src != '\n' && *src != 26) {
if (*src >= 'A' && *src <= 'Z')
*dst++ = *src++ + 'a' - 'A'; /* tolower */
else
*dst++ = *src++;
}
*dst = 0;
src = sows(src);
return src;
}
static int
lookuptoken(ptr)
char *ptr;
{
int i;
if (ptr[strlen(ptr) - 1] != ':')
for (i = 1; i < NTOKENS; i++)
if (!strcmp(ptr, tokens[i]))
return i;
return NOTOKEN;
}
static int
tokentoint(s, ret)
char *s;
int *ret;
{
int i;
for (i = 0; i < strlen(s); i++)
if (!isdigit(s[i]) && s[i] != '-')
return 0;
sscanf(s, "%d", ret);
return 1;
}
static void
addlabel(ex, s)
ExecStruct *ex;
char *s;
{
ex->label[ex->numlabels].string = strdup(s);
ex->label[ex->numlabels].ipaddr = ex->numcodes;
if (++(ex->numlabels) >= MAXLABELS)
error("%s: too many labels!");
}
static void
addargcount(ex, tokenaddr)
ExecStruct *ex;
int tokenaddr;
{
ex->Code[tokenaddr].val.i = ex->numcodes - tokenaddr - 1;
}
static void
addtoken(ex, t)
ExecStruct *ex;
int t;
{
ex->Code[ex->numcodes].token = t;
if (++(ex->numcodes) >= MAXCODES)
error("%s: text file too large. can only have %d tokens\n", MAXCODES);
}
static void
addstring(ex, string)
ExecStruct *ex;
char *string;
{
ex->Code[ex->numcodes].val.s = strdup(string);
addtoken(ex, STRING);
}
static void
addint(token, arg, ex, string, integer)
int token;
int arg;
ExecStruct *ex;
char *string;
int integer;
{
/*
* make sure we don't convert a string that happens to parse as a number
* such as a filename, or keyname, or video mode, into an integer
*/
if (((token == CLOAD || token == PLOAD || token == FLOAD)
&& (arg == 1))
|| (token == TEXT && arg == 3)
|| (token == VIDEO || token == IFKEY))
addstring(ex, string);
else {
ex->Code[ex->numcodes].val.i = integer;
addtoken(ex, INTEGER);
}
}
void
parsefile(ex, ptr)
ExecStruct *ex;
char *ptr;
{
char buffer[100];
int tokenaddr;
ex->numcodes = 0;
ex->numlabels = 0;
do {
int i;
int token;
ptr = copytoken(ptr, buffer);
if (buffer[0] == 0)
break;
if (buffer[strlen(buffer) - 1] == ':') {
buffer[strlen(buffer) - 1] = 0;
addlabel(ex, buffer);
while (*ptr != '\n' && *ptr != 26)
ptr++;
} else {
int range;
int start;
token = lookuptoken(buffer);
if (token == NOTOKEN) {
if (tokentoint(buffer, &i))
addint(token, 0, ex, buffer, i);
else
addstring(ex, buffer);
tokenaddr = -1;
} else {
tokenaddr = ex->numcodes;
addtoken(ex, token);
}
range = 0;
while (*ptr != '\n' && *ptr != 26) {
int arg = ex->numcodes - tokenaddr;
ptr = copytoken(ptr, buffer);
if (range) {
if (tokentoint(buffer, &i)) {
int val;
if (i >= start)
for (val = start; val <= i; val++)
addint(token, arg, ex, buffer, val);
else
for (val = start; val >= i; val--)
addint(token, arg, ex, buffer, val);
range = 0;
} else
error("%s: parse error on int range\n");
} else {
if (buffer[0] == '-' && buffer[1] == 0) {
range = 1;
} else {
if (tokentoint(buffer, &i)) {
addint(token, arg, ex, buffer, i);
start = i;
} else
addstring(ex, buffer);
}
}
}
if (tokenaddr != -1)
addargcount(ex, tokenaddr);
}
if (*ptr == 26)
break;
ptr++;
} while (*ptr != 26);
}